#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <asm/io.h>
#include "led_opr.h"

static volatile unsigned int *CCM_CCGR1 ;
static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
static volatile unsigned int *GPIO5_GDIR ;
static volatile unsigned int *GPIO5_DR ;

static int board_led_init(int which)
{
    unsigned int val;
    if(which == 0)
    {
        if(!CCM_CCGR1)
        {
            CCM_CCGR1 = ioremap(0x20c406c, 4);
            IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = ioremap(0x2290000 + 0x14, 4);
            GPIO5_GDIR = ioremap(0x20ac004, 4);
            GPIO5_DR = ioremap(0x20ac000, 4	);
        }
        	/* 打开GPIO5时钟 */
        *CCM_CCGR1 |= (0x3<<30);

        /*配置为GPIO5_03*/
        val = *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
        val &= ~0Xf;
        val |= 0x5;
        *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = val;
        /*GPIO5_03配置为输出*/
	    *GPIO5_GDIR |= (1<<3);
    }
    return 0;
}


static int board_led_ctl(int which, char status)
{
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    if(which == 0)
    {
        if(status)
        {
            *GPIO5_DR |= (1<<3);  // output:1
        }
        else
        {
            *GPIO5_DR &= ~(1<<3);  // output:0
        }
    }
	return 0;
}

static int board_led_destroy(void)
{
    iounmap(CCM_CCGR1);
    iounmap(IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3);
    iounmap(GPIO5_GDIR);
    iounmap(GPIO5_DR);

	return 0;
}

static struct led_oprations board_demo_led_opr = {
    .num        = 1,
    .init       = board_led_init,
    .ctl        = board_led_ctl,
    .destroy    = board_led_destroy,
};

struct led_oprations *get_board_led_opr(void)
{
    return &board_demo_led_opr;
}
